home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-13 / tde3.zip / HWIND.C < prev    next >
C/C++ Source or Header  |  1993-06-05  |  15KB  |  521 lines

  1. /*******************  start of original comments  ********************/
  2. /*
  3.  * Written by Douglas Thomson (1989/1990)
  4.  *
  5.  * This source code is released into the public domain.
  6.  */
  7.  
  8. /*
  9.  * Name:    hardware independent screen IO module
  10.  * Purpose: This file contains the code to interface the rest of the
  11.  *           editor to the display and input hardware.
  12.  * File:    hwind.c
  13.  * Author:  Douglas Thomson
  14.  * System:  this file is intended to be system-independent
  15.  * Date:    October 2, 1989
  16.  * Notes:   This is the only module that is allowed to call the hardware
  17.  *           dependent display IO library.
  18.  *          Typically, functions here check whether any action is
  19.  *           necessary (for example, the cursor may already happen to be
  20.  *           in the required position), call hardware dependent functions
  21.  *           to achieve the required effect, and finally update status
  22.  *           information about the current state of the terminal display.
  23.  *          The idea behind this approach is to keep the hardware
  24.  *           dependent code as small and simple as possible, thus making
  25.  *           porting the code easier.
  26.  */
  27. /*********************  end of original comments   ********************/
  28.  
  29.  
  30. /*
  31.  * Some routines were added to display current editor modes in the lite bar
  32.  * at the bottom of the screen. Other routines were rewritten in assembly.
  33.  * I feel the need for speed.
  34.  *
  35.  * New editor name:  TDE, the Thomson-Davis Editor.
  36.  * Author:           Frank Davis
  37.  * Date:             June 5, 1991, version 1.0
  38.  * Date:             July 29, 1991, version 1.1
  39.  * Date:             October 5, 1991, version 1.2
  40.  * Date:             January 20, 1992, version 1.3
  41.  * Date:             February 17, 1992, version 1.4
  42.  * Date:             April 1, 1992, version 1.5
  43.  * Date:             June 5, 1992, version 2.0
  44.  * Date:             October 31, 1992, version 2.1
  45.  * Date:             April 1, 1993, version 2.2
  46.  * Date:             June 5, 1993, version 3.0
  47.  *
  48.  * This modification of Douglas Thomson's code is released into the
  49.  * public domain, Frank Davis.  You may distribute it freely.
  50.  */
  51.  
  52. #include <bios.h>       /* for REGS */
  53. #include <dos.h>        /* for intdos */
  54.  
  55. #include "tdestr.h"
  56. #include "common.h"
  57. #include "tdefunc.h"
  58. #include "define.h"
  59.  
  60.  
  61. /*
  62.  * Name:    get_date
  63.  * Purpose: get system date from DOS
  64.  * Date:    June 5, 1992
  65.  * Passed:  year:  pointer to integer to store year
  66.  *          month: pointer to integer to store month
  67.  *          day:   pointer to integer to store day
  68.  *          day_of_week:  pointer to integer to store dow
  69.  * Notes:   call standard DOS interrupt 0x21, function 0x2a to get the date.
  70.  */
  71. void get_date( int *year, int *month, int *day, int *day_of_week  )
  72. {
  73. union REGS inregs, outregs;
  74.  
  75.    inregs.h.ah = 0x2a;
  76.    intdos( &inregs, &outregs );
  77.    *year        = (int)outregs.x.cx;
  78.    *month       = (int)outregs.h.dh;
  79.    *day         = (int)outregs.h.dl;
  80.    *day_of_week = (int)outregs.h.al;
  81. }
  82.  
  83.  
  84. /*
  85.  * Name:    get_time
  86.  * Purpose: get system time from DOS
  87.  * Date:    June 5, 1992
  88.  * Passed:  hour:  pointer to integer to store hour - system returns 24 hour
  89.  *          minutes:  pointer to integer to store minutes
  90.  *          seconds:  pointer to integer to store seconds
  91.  *          hundredths:  pointer to integer to store hundredths of second
  92.  * Notes:   call standard DOS interrupt 0x21, function 0x2c to get the time.
  93.  */
  94. void get_time( int *hour, int *minutes, int *seconds, int *hundredths  )
  95. {
  96. union REGS inregs, outregs;
  97.  
  98.    inregs.h.ah = 0x2c;
  99.    intdos( &inregs, &outregs );
  100.    *hour       = (int)outregs.h.ch;
  101.    *minutes    = (int)outregs.h.cl;
  102.    *seconds    = (int)outregs.h.dh;
  103.    *hundredths = (int)outregs.h.dl;
  104. }
  105.  
  106.  
  107. /*
  108.  * Name:    show_modes
  109.  * Purpose: show current editor modes in lite bar at bottom of screen
  110.  * Date:    June 5, 1991
  111.  */
  112. void show_modes( void )
  113. {
  114. char status_line[MAX_COLS+2];
  115.  
  116.    memset( status_line, ' ', MAX_COLS );
  117.    status_line[MAX_COLS] = '\0';
  118.    s_output( status_line, g_display.mode_line, 0, g_display.mode_color );
  119.    s_output( "F=   W=", g_display.mode_line, 1, g_display.mode_color );
  120.    s_output( "m=", g_display.mode_line, 12, g_display.mode_color );
  121.    show_window_count( g_status.window_count );
  122.    show_file_count( g_status.file_count );
  123.    show_avail_mem( );
  124.    show_tab_modes( );
  125.    show_indent_mode( );
  126.    show_sync_mode( );
  127.    show_control_z( );
  128.    show_insert_mode( );
  129.    show_search_case( );
  130.    show_wordwrap_mode( );
  131.    show_trailing( );
  132. }
  133.  
  134.  
  135. /*
  136.  * Name:    show_file_count
  137.  * Purpose: show number of open files in lite bar at bottom of screen
  138.  * Passed:  fc:  file count - number of open files
  139.  * Date:    June 5, 1991
  140.  */
  141. void show_file_count( int fc )
  142. {
  143. char status_line[MAX_COLS+2];
  144.  
  145.    s_output( "  ", g_display.mode_line, 3, g_display.mode_color );
  146.    s_output( itoa( fc, status_line, 10 ), g_display.mode_line, 3,
  147.              g_display.mode_color );
  148. }
  149.  
  150.  
  151. /*
  152.  * Name:    show_window_count
  153.  * Purpose: show total number of windows in lite bar at bottom of screen
  154.  * Passed:  wc:  window count - visible and hidden.
  155.  * Date:    September 13, 1991
  156.  */
  157. void show_window_count( int wc )
  158. {
  159. char status_line[MAX_COLS+2];
  160.  
  161.    s_output( "  ", g_display.mode_line, 8, g_display.mode_color );
  162.    s_output( itoa( wc, status_line, 10 ), g_display.mode_line, 8,
  163.              g_display.mode_color );
  164. }
  165.  
  166.  
  167. /*
  168.  * Name:    show_avail_mem
  169.  * Purpose: show available free memory in lite bar at bottom of screen
  170.  * Date:    June 5, 1991
  171.  */
  172. void show_avail_mem( void )
  173. {
  174. char line[MAX_COLS+2];
  175. unsigned long avail_mem;
  176.  
  177. #if defined( __MSC__ )
  178. unsigned paragraphs;
  179.  
  180.    _dos_allocmem( 0xffff, ¶graphs );
  181.    /*
  182.     * A paragraph is 16 bytes.  Convert paragraphs to bytes by shifting left
  183.     * 4 bits.
  184.     */
  185.    avail_mem = (long)paragraphs << 4;
  186. #else
  187.    avail_mem = farcoreleft( );
  188. #endif
  189.  
  190.    s_output( "        ", g_display.mode_line, 14, g_display.mode_color );
  191.    ultoa( avail_mem, line, 10 );
  192.    s_output( line, g_display.mode_line, 14,
  193.              g_display.mode_color );
  194. }
  195.  
  196.  
  197. /*
  198.  * Name:    show_tab_modes
  199.  * Purpose: show smart tab mode in lite bar at bottom of screen
  200.  * Date:    October 31, 1992
  201.  */
  202. void show_tab_modes( void )
  203. {
  204. char *blank_tab = "   ";
  205. char ascii_tab[10];
  206.  
  207.    s_output( tabs, g_display.mode_line, 22, g_display.mode_color );
  208.    s_output( mode.smart_tab ? smart : fixed, g_display.mode_line, 27,
  209.              g_display.mode_color );
  210.    s_output( mode.inflate_tabs ? intab : outtab, g_display.mode_line, 28,
  211.              g_display.mode_color );
  212.    s_output( blank_tab, g_display.mode_line, 29, g_display.mode_color );
  213.    s_output( itoa( mode.ptab_size, ascii_tab, 10), g_display.mode_line, 29,
  214.              g_display.mode_color );
  215. }
  216.  
  217.  
  218. /*
  219.  * Name:    show_indent_mode
  220.  * Purpose: show indent mode in lite bar at bottom of screen
  221.  * Date:    June 5, 1991
  222.  */
  223. void show_indent_mode( void )
  224. {
  225.    s_output( mode.indent ? indent : blank, g_display.mode_line, 32,
  226.              g_display.mode_color );
  227. }
  228.  
  229.  
  230. /*
  231.  * Name:    show_search_case
  232.  * Purpose: show search mode in lite bar
  233.  * Date:    June 5, 1991
  234.  */
  235. void show_search_case( void )
  236. {
  237.    s_output( mode.search_case == IGNORE ? ignore : match, g_display.mode_line,
  238.              40, g_display.mode_color );
  239. }
  240.  
  241.  
  242. /*
  243.  * Name:    show_sync_mode
  244.  * Purpose: show sync mode in lite bar
  245.  * Date:    January 15, 1992
  246.  */
  247. void show_sync_mode( void )
  248. {
  249.    s_output( mode.sync ? sync_on : sync_off, g_display.mode_line, 48,
  250.              g_display.mode_color );
  251. }
  252.  
  253.  
  254. /*
  255.  * Name:    show_wordwrap_mode
  256.  * Purpose: display state of word wrap mode
  257.  * Date:    June 5, 1991
  258.  */
  259. void show_wordwrap_mode( void )
  260. {
  261.    s_output( ww_mode[mode.word_wrap], g_display.mode_line, 54,
  262.              g_display.mode_color );
  263. }
  264.  
  265.  
  266. /*
  267.  * Name:    show_trailing
  268.  * Purpose: show state of trailing flag
  269.  * Date:    June 5, 1991
  270.  */
  271. void show_trailing( void )
  272. {
  273.    c_output( mode.trailing ? 'T' : ' ', 66, g_display.mode_line,
  274.              g_display.mode_color );
  275. }
  276.  
  277.  
  278. /*
  279.  * Name:    show_control_z
  280.  * Purpose: show state of control z flag
  281.  * Date:    June 5, 1991
  282.  */
  283. void show_control_z( void )
  284. {
  285.    c_output( mode.control_z ? 'Z' : ' ', 77, g_display.mode_line,
  286.              g_display.mode_color );
  287. }
  288.  
  289.  
  290. /*
  291.  * Name:    show_insert_mode
  292.  * Purpose: show insert mode in lite bar
  293.  * Date:    June 5, 1991
  294.  */
  295. void show_insert_mode( void )
  296. {
  297.    c_output( mode.insert ? 'i' : 'o', 79, g_display.mode_line,
  298.              g_display.mode_color );
  299. }
  300.  
  301.  
  302. /*
  303.  * Name:    my_scroll_down
  304.  * Purpose: display a portion of a window
  305.  * Date:    June 5, 1991
  306.  * Passed:  window:  pointer to current window
  307.  * Notes:   Using the bios scroll functions causes a slightly noticable
  308.  *            "flicker", even on fast VGA monitors.  This is caused by changing
  309.  *            the high-lited cursor line to text color then calling the bios
  310.  *            function to scroll.  Then, the current line must then be
  311.  *            hilited.
  312.  *          This function assumes that win->cline is the current line.
  313.  */
  314. void my_scroll_down( WINDOW *window )
  315. {
  316. int  i;
  317. int  curl;
  318. int  eof;
  319. WINDOW w;              /* scratch window struct for dirty work */
  320.  
  321.    if (!window->visible  ||  !g_status.screen_display)
  322.       return;
  323.    dup_window_info( &w, window );
  324.    curl = i = window->bottom_line + 1 - window->cline;
  325.    eof = FALSE;
  326.    for (; i>0; i--) {
  327.       if (w.ll->len != EOF) {
  328.          /*
  329.           * if this is window->cline, do not show the line because we
  330.           * show the curl at the end of this function.  don't show it twice
  331.           */
  332.          if (i != curl)
  333.             update_line( &w );
  334.       } else if (eof == FALSE) {
  335.          show_eof( &w );
  336.          eof = TRUE;
  337.       } else
  338.          window_eol_clear( &w, COLOR_TEXT );
  339.       if (w.ll->next != NULL)
  340.          w.ll = w.ll->next;
  341.       ++w.cline;
  342.       ++w.rline;
  343.    }
  344.    show_curl_line( window );
  345. }
  346.  
  347.  
  348. /*
  349.  * Name:    combine_strings
  350.  * Purpose: stick 3 strings together
  351.  * Date:    June 5, 1991
  352.  * Passed:  buff:    buffer to hold concatenation of 3 strings
  353.  *          s1:  pointer to string 1
  354.  *          s2:  pointer to string 2
  355.  *          s3:  pointer to string 3
  356.  */
  357. void combine_strings( char *buff, char *s1, char *s2, char *s3 )
  358. {
  359.    assert( strlen( s1 ) + strlen( s2 ) + strlen( s3 ) < MAX_COLS );
  360.    strcpy( buff, s1 );
  361.    strcat( buff, s2 );
  362.    strcat( buff, s3 );
  363. }
  364.  
  365.  
  366. /*
  367.  * Name:    make_ruler
  368.  * Purpose: make ruler with tabs, tens, margins, etc...
  369.  * Date:    June 5, 1991
  370.  * Passed:  window:  pointer to current window
  371.  */
  372. void make_ruler( WINDOW *window )
  373. {
  374. register WINDOW *win;
  375. char num[20];
  376. register unsigned char *p;
  377. int  len;
  378. int  col;
  379. int  i;
  380. int  mod;
  381.  
  382.    win = window;
  383.  
  384.    /*
  385.     * need to have a least two lines in a window when we display a ruler.
  386.     */
  387.    if (win->bottom_line - win->top_line < 1)
  388.       win->ruler = FALSE;
  389.    if (win->ruler) {
  390.  
  391.       /*
  392.        * find the width of the window and fill the ruler with dots.
  393.        */
  394.       len = win->end_col + 1 - win->start_col;
  395.  
  396.       assert( len >= 0 );
  397.       assert( len <= MAX_COLS );
  398.  
  399.       memset( win->ruler_line, RULER_FILL, len );
  400.       win->ruler_line[len] = '\0';
  401.       col = win->bcol+1;
  402.  
  403.       assert( col >= 1 );
  404.       assert( col <= MAX_LINE_LENGTH );
  405.  
  406.       for (p=(unsigned char *)win->ruler_line; *p; col++, p++) {
  407.  
  408.          /*
  409.           * put a tens digit in the tens column
  410.           */
  411.          mod = col % 10;
  412.          if (mod == 0) {
  413.             itoa( col/10, num, 10 );
  414.  
  415.             /*
  416.              * let the margin chars have precidence over tens digit
  417.              */
  418.             for (i=0; num[i] && *p; col++, i++) {
  419.                if (col == mode.left_margin+1)
  420.                   *p = LM_CHAR;
  421.                else if (col == mode.right_margin+1) {
  422.                   if (mode.right_justify == TRUE)
  423.                      *p = RM_CHAR_JUS;
  424.                   else
  425.                      *p = RM_CHAR_RAG;
  426.                } else if (col == mode.parg_margin+1)
  427.                   *p = PGR_CHAR;
  428.                else
  429.                   *p = num[i];
  430.                p++;
  431.             }
  432.  
  433.             /*
  434.              * we may have come to the end of the ruler in the for loop.
  435.              */
  436.             if (*p == '\0')
  437.                break;
  438.          } else if (mod == 5)
  439.             *p = RULER_TICK;
  440.          if (col == mode.parg_margin+1)
  441.             *p = PGR_CHAR;
  442.          if (col == mode.left_margin+1)
  443.             *p = LM_CHAR;
  444.          else if (col == mode.right_margin+1) {
  445.             if (mode.right_justify == TRUE)
  446.                *p = RM_CHAR_JUS;
  447.             else
  448.                *p = RM_CHAR_RAG;
  449.          }
  450.       }
  451.    }
  452. }
  453.  
  454.  
  455. /*
  456.  * Name:    show_ruler
  457.  * Purpose: show ruler with tens, margins, etc...
  458.  * Date:    June 5, 1991
  459.  * Passed:  window:  pointer to current window
  460.  */
  461. void show_ruler( WINDOW *window )
  462. {
  463.    if (window->ruler && window->visible)
  464.       s_output( window->ruler_line, window->top_line, window->start_col,
  465.                 g_display.ruler_color );
  466. }
  467.  
  468.  
  469. /*
  470.  * Name:    show_ruler_char
  471.  * Purpose: show ruler character under ruler pointer
  472.  * Date:    June 5, 1991
  473.  * Passed:  window:  pointer to current window
  474.  */
  475. void show_ruler_char( WINDOW *window )
  476. {
  477. register WINDOW *win;
  478. char c;
  479.  
  480.    win = window;
  481.    if (win->ruler && win->visible) {
  482.       c = win->ruler_line[win->ccol - win->start_col];
  483.       c_output( c, win->ccol, win->top_line, g_display.ruler_color );
  484.    }
  485. }
  486.  
  487.  
  488. /*
  489.  * Name:    show_ruler_pointer
  490.  * Purpose: show ruler pointer
  491.  * Date:    June 5, 1991
  492.  * Passed:  window:  pointer to current window
  493.  */
  494. void show_ruler_pointer( WINDOW *window )
  495. {
  496.    if (window->ruler && window->visible)
  497.       c_output( RULER_PTR, window->ccol, window->top_line,
  498.                 g_display.ruler_pointer );
  499. }
  500.  
  501.  
  502. /*
  503.  * Name:    show_all_rulers
  504.  * Purpose: make and show all rulers in all visible windows
  505.  * Date:    June 5, 1991
  506.  */
  507. void show_all_rulers( void )
  508. {
  509. register WINDOW *wp;
  510.  
  511.    wp = g_status.window_list;
  512.    while (wp != NULL) {
  513.       make_ruler( wp );
  514.       if (wp->visible) {
  515.          show_ruler( wp );
  516.          show_ruler_pointer( wp );
  517.       }
  518.       wp = wp->next;
  519.    }
  520. }
  521.